home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 24
/
Mac Magazin and MacEasy Magazine CD - Issue 24.iso
/
Grafik & Text
/
Microsoft Installer Patch
/
patches.c
< prev
next >
Wrap
Text File
|
1996-07-13
|
4KB
|
186 lines
// patches.c
#include <Traps.h>
#include <A4Stuff.h>
#include "patches.h"
// defines
#define CurApName (0x911)
#define VALID(name) ((name) && (((long)(name))&0xFFFF) && ((((long)(name))>>16)&0xFFFF))
#define pstrcpy(s1,s2) do { *(s1) = 0; pstrcat(s1,s2); } while(false)
// prototypes
inline void pstrcat( StringPtr s1, StringPtr s2 );
Boolean my_strncmp( void* s1, void* s2, short n );
// globals
extern Str63 volumeName;
extern short volumeVRef;
void PatchFSDispatch( void )
{
short trap = _FSDispatch;
Ptr data;
Ptr patch = (Ptr)MyFSDispatch;
// fill in the necessary fields in
data = (Ptr)NGetTrapAddress( trap, (trap & 0x0800) ? ToolTrap : OSTrap);
BlockMove( &data, patch+2, sizeof(data) );
data = (Ptr)FSDispatchHelper;
BlockMove( &data, patch+6, sizeof(data) );
// patch it
NSetTrapAddress( (UniversalProcPtr)MyFSDispatch, trap, (trap & 0x0800) ? ToolTrap : OSTrap);
}
inline void pstrcat( StringPtr s1, StringPtr s2 )
{
BlockMoveData( s2+1, s1+s1[0]+1, s2[0] );
s1[0] += s2[0];
}
Boolean my_strncmp( void* s1, void* s2, short n )
{
register Ptr p1 = (Ptr)s1, p2 = (Ptr)s2;
while (n--)
if (*(p2++) != *(p1++)) return false;
return true;
}
asm void MyFSDispatch( void )
{
bra.s Begin
Real_FSDispatch:
dc.l 0 // Saved address of the real FSDispatch code
FSDispatchHelper:
dc.l 0 // our helper routine, which messes with the
// parameter (FileParam*) we pass it...
Begin:
movem.l d0-d2/a0-a2, -(a7) // save volatile registers
// okay, now we have a selector in D0, and a
// pointer to a fileParam in A0, because that's
// the way FSDispatch works.
// let's jump off to our wonderful friend the helper function,
// to look at all the crap that got passed and see if we should
// modify what it says.
move.l a0, -(a7) // push the FileParam onto the stack
move.l FSDispatchHelper, a0 // load FSDispatchHelper
jsr (a0) // call it
add.l #4, a7 // fix the stack
// Clean up
movem.l (a7)+, d0-d2/a0-a2
// Pass control to the real FSDispatch
move.l Real_FSDispatch, a1
jmp (a1)
}
void FSDispatchHelper( FileParam *pb )
{
static Str255 patchedName;
EnterCodeResource();
// make sure pb is valid
if (!pb) goto done;
// make sure we're only messing with the Microsoft installer
if ( !(*(long*)CurApName == 'Micr') ) goto done;
// and make sure we've got a real ptr
if ( !VALID(pb->ioNamePtr) ) goto done;
// first, if it's talking about the root directory
// notice we're not bothering to discuss the parameter; this
// is bad monkey but it's much easier this way...
if ((pb->ioVRefNum == -1 || pb->ioVRefNum == 0) &&
pb->ioFlNum == 2 )
{
// see if it's talking about the Microsoft folder
if ( my_strncmp( pb->ioNamePtr+1, "Microsoft", 9 ) )
{
if ( (pb->ioNamePtr[0]==9) || // ref to the folder itself
((pb->ioNamePtr[0]>=10) && (pb->ioNamePtr[10]==':')) ) // or something inside
{
pstrcpy( patchedName, "\p:System Folder:" );
pstrcat( patchedName, pb->ioNamePtr );
pstrcpy( pb->ioNamePtr, patchedName );
goto done;
}
}
}
// see if it's giving a full pathname
if ( my_strncmp( pb->ioNamePtr+1, volumeName+1, *volumeName ) &&
my_strncmp( pb->ioNamePtr+1+*volumeName, ":Microsoft", 10 ) )
{
// sure looks like it; check further though
if ( (pb->ioNamePtr[0]==*volumeName+10) || // ref to the folder itself
((pb->ioNamePtr[0]>(*volumeName+10)) && (pb->ioNamePtr[*volumeName+12]==':')) ) // something inside
{
pstrcpy( patchedName, volumeName );
pstrcat( patchedName, "\p:System Folder:" );
pb->ioNamePtr[*volumeName+11] = pb->ioNamePtr[0] - (*volumeName+1);
pstrcat( patchedName, pb->ioNamePtr );
pstrcpy( pb->ioNamePtr, patchedName );
goto done;
}
}
// see if it's a partial path based off the root dir
if ( pb->ioFlNum == 0 && (pb->ioVRefNum==0 || pb->ioVRefNum==-1) )
{
// ok, are we talking about the Microsoft folder?
if ( my_strncmp(pb->ioNamePtr + 1,":Microsoft",10) )
{
if ( (pb->ioNamePtr[0]==10) || // ref to the folder itself
((pb->ioNamePtr[0]>=11) && (pb->ioNamePtr[11]==':')) ) // something inside
{
pstrcpy( patchedName, "\p:System Folder" );
pstrcat( patchedName, pb->ioNamePtr );
pstrcpy( pb->ioNamePtr, patchedName );
goto done;
}
}
}
// else it looks like we don't do anything.
done:
ExitCodeResource();
return;
}